package com.example.access_control.Controller;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.access_control.AccessControl.AccessControlInit;
import com.example.access_control.AccessControl.Commom.osSelect;
import com.example.access_control.AccessControl.NetSDKDemo.HCNetSDK;
import com.example.access_control.entity.AccessControl;
import com.example.access_control.entity.AccessControlLog;
import com.example.access_control.service.AccessControlLogService;
import com.example.access_control.service.AccessControlService;
import com.sun.jna.Native;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Slf4j
@RestController
@RequestMapping("/hk/server")
public class ServerController {

    @Resource
    public AccessControlService accessControlService;
    @Autowired
    public AccessControlInit accessControlInit;
    @Resource
    public AccessControlLogService accessControlLogService;


    public static int lUserID = -1;//用户句柄
    public static HCNetSDK hCNetSDK = null;


    private boolean createSDKInstance() {
        if (hCNetSDK == null) {
            synchronized (HCNetSDK.class) {
                String strDllPath = "";
                try {
                    //System.setProperty("jna.debug_load", "true");
                    if (osSelect.isWindows())
                        //win系统加载库路径
                        strDllPath = System.getProperty("user.dir") + "\\libs\\AccessControl\\win\\HCNetSDK.dll";
                    else if (osSelect.isLinux())
                        //Linux系统加载库路径
                        strDllPath = System.getProperty("user.dir") + "/libs/AccessControl/linux/libhcnetsdk.so";
                    hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class);
                } catch (Exception ex) {
                    System.out.println("loadLibrary: " + strDllPath + " Error: " + ex.getMessage());
                    return false;
                }
            }
        }
        return true;
    }


    /**
     * 登录设备，支持 V40 和 V30 版本，功能一致。
     *
     * @param ip   设备IP地址
     * @param port SDK端口，默认为设备的8000端口
     * @param user 设备用户名
     * @param psw  设备密码
     * @return 登录成功返回用户ID，失败返回-1
     */
    public int loginDevice(String ip, short port, String user, String psw) {
        // 创建设备登录信息和设备信息对象
        HCNetSDK.NET_DVR_USER_LOGIN_INFO loginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
        HCNetSDK.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();

        // 设置设备IP地址
        byte[] deviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
        byte[] ipBytes = ip.getBytes();
        System.arraycopy(ipBytes, 0, deviceAddress, 0, Math.min(ipBytes.length, deviceAddress.length));
        loginInfo.sDeviceAddress = deviceAddress;

        // 设置用户名和密码
        byte[] userName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
        byte[] password = psw.getBytes();
        System.arraycopy(user.getBytes(), 0, userName, 0, Math.min(user.length(), userName.length));
        System.arraycopy(password, 0, loginInfo.sPassword, 0, Math.min(password.length, loginInfo.sPassword.length));
        loginInfo.sUserName = userName;

        // 设置端口和登录模式
        loginInfo.wPort = port;
        loginInfo.bUseAsynLogin = false; // 同步登录
        loginInfo.byLoginMode = 0; // 使用SDK私有协议

        // 执行登录操作
        int userID = hCNetSDK.NET_DVR_Login_V40(loginInfo, deviceInfo);
        if (userID == -1) {
            System.err.println("登录失败，错误码为: " + hCNetSDK.NET_DVR_GetLastError());
        } else {
            System.out.println(ip + " 设备登录成功！");
            // 处理通道号逻辑
//			int startDChan = deviceInfo.struDeviceV30.byStartDChan;
//			System.out.println("预览起始通道号: " + startDChan);
        }
        return userID; // 返回登录结果
    }

    /**
     * 远程控门
     *
     * @param data
     * @return
     */
    @PostMapping("/door/control")
    @ResponseBody
    public String openDoor(@RequestBody JSONObject data) {
        if (StrUtil.isEmpty(data.getStr("accessControlId"))) {
            return "fill";
        }

//        if (hCNetSDK == null) {
//            if (!createSDKInstance()) {
//                System.out.println("Load SDK fail");
//                return "fail";
//            }
//        }
//        //linux系统建议调用以下接口加载组件库
//        if (osSelect.isLinux()) {
//            HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
//            HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
//            //这里是库的绝对路径，请根据实际情况修改，注意改路径必须有访问权限
//            String strPath1 = System.getProperty("user.dir") + "/lib/libcrypto.so.1.1";
//            String strPath2 = System.getProperty("user.dir") + "/lib/libssl.so.1.1";
//            System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
//            ptrByteArray1.write();
//            hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_LIBEAY_PATH, ptrByteArray1.getPointer());
//            System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
//            ptrByteArray2.write();
//            hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_SSLEAY_PATH, ptrByteArray2.getPointer());
//            String strPathCom = System.getProperty("user.dir") + "/lib/";
//            HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
//            System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
//            struComPath.write();
//            hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_SDK_PATH, struComPath.getPointer());
//        }
//        //SDK初始化，和进程保持同步，仅需要调用一次
//        hCNetSDK.NET_DVR_Init();
//        //开启SDK日志打印
//        hCNetSDK.NET_DVR_SetLogToFile(3, "./sdklog", false);
//        //设备登录
//        lUserID = loginDevice("192.168.6.103", (short) 8000, "admin", "zxkj1234560.");    //登陆设备
//        ACSManage.remoteControlGate(lUserID);


//        AccessControl accessControl = accessControlService.getById(data.getInt("accessControlId"));
        log.info("[Module]远程控门");
        try {
            accessControlInit.remoteControlGate(data.getInt("accessControlId"), data.getInt("dwStaic"));
            return "success";
        } catch (Exception e) {
            log.error("远程控门失败", e);
            return "fail";
        }
    }

    /**
     * 设置语音播报
     * switch 1: 打开语音播报
     * switch 0: 关闭语音播报
     */
    @PostMapping("/set/voice")
    @ResponseBody
    public String setVoice(@RequestBody JSONObject data) {
        if (StrUtil.isEmpty(data.getStr("accessControlId"))) {
            return "fill";
        }
        log.info("[Module]设置语音播报");
//        AccessControl accessControl = accessControlService.getById(data.getInt("accessControlId"));
        accessControlInit.setVoice(data.getInt("accessControlId"), data.getInt("switchStatus"));
        return "success";
    }

    /**
     * 获取事件
     */
    @PostMapping("/event/get")
    @ResponseBody
    public String getEvent(@RequestBody JSONObject data) throws InterruptedException {
        log.info("[Module]获取事件");
        Date date = DateUtil.date();
        DateTime offsetDateTime = DateUtil.offsetMinute(date, -15);
        Date offsetDate = DateUtil.date(offsetDateTime);
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("offsetYear", DateUtil.year(offsetDate));
        paramsMap.put("offsetMonth", DateUtil.month(offsetDate) + 1);
        paramsMap.put("offsetDay", DateUtil.dayOfMonth(offsetDate));
        paramsMap.put("offsetHour", DateUtil.hour(offsetDate, true));
        paramsMap.put("offsetMinute", DateUtil.minute(offsetDate));
        paramsMap.put("offsetSecond", DateUtil.second(offsetDate));
        paramsMap.put("year", DateUtil.year(date));
        paramsMap.put("month", DateUtil.month(date) + 1);
        paramsMap.put("day", DateUtil.dayOfMonth(date));
        paramsMap.put("hour", DateUtil.hour(date, true));
        paramsMap.put("minute", DateUtil.minute(date));
        paramsMap.put("second", DateUtil.second(date));
        paramsMap.put("accessControlId", data.getInt("accessControlId"));
        paramsMap.put("date", DateUtil.formatDateTime(date));
        paramsMap.put("offsetDate", DateUtil.formatDateTime(offsetDate));
        // 人脸识别通过后，获取事件
        List<AccessControlLog> faceAccessControlLogList = accessControlInit.searchAllEvent(paramsMap,5,75,1);
        if (!faceAccessControlLogList.isEmpty()) {
            accessControlLogService.saveBatch(faceAccessControlLogList);
            log.info("保存人脸识别日志成功");
        }
        // 刷卡识别通过后，获取事件
        List<AccessControlLog> accessControlLogList = accessControlInit.searchAllEvent(paramsMap,5,1,2);
        if (!accessControlLogList.isEmpty()) {
            accessControlLogService.saveBatch(accessControlLogList);
            log.info("保存刷卡日志成功");
        }
//        // 远程开门
//        List<AccessControlLog> openDoorAccessControlLogList = accessControlInit.searchAllEvent(paramsMap,3,1024,3);
//        if (!openDoorAccessControlLogList.isEmpty()) {
//            accessControlLogService.saveBatch(openDoorAccessControlLogList);
//            log.info("保存远程开门日志成功");
//        }
//        // 远程关门
//        List<AccessControlLog> closeDoorAccessControlLogList = accessControlInit.searchAllEvent(paramsMap,3,1025,4);
//        if (!closeDoorAccessControlLogList.isEmpty()) {
//            accessControlLogService.saveBatch(closeDoorAccessControlLogList);
//            log.info("保存远程关门日志成功");
//        }
//        // 远程常开
//        List<AccessControlLog> remoteNormallyOpenLogList = accessControlInit.searchAllEvent(paramsMap,3,1026,5);
//        if (!remoteNormallyOpenLogList.isEmpty()) {
//            accessControlLogService.saveBatch(remoteNormallyOpenLogList);
//            log.info("保存远程常开日志成功");
//        }
//        // 远程常闭
//        List<AccessControlLog> remoteNormallyCloseLogList = accessControlInit.searchAllEvent(paramsMap,3,1027,6);
//        if (!remoteNormallyCloseLogList.isEmpty()) {
//            accessControlLogService.saveBatch(remoteNormallyCloseLogList);
//            log.info("保存远程常闭日志成功");
//        }
        return "success";
    }

}
